package com.lzp.java.concurrent.threadcore.threadandobject.object;

import java.io.IOException;

/**
 * WAITING状态被中断唤醒或者TIME-WAITING超时唤醒后，仍然需要获取锁
 */
public class WaitingStatusInterruptNeedGetMonitor {

    public static void main(String[] args) {
        Thread1 thread1 = new Thread1();
        Thread2 thread2 = new Thread2(thread1);
        thread1.start();
        thread2.start();

    }

    private static Object resource = new Object();

    static class Thread1 extends Thread {

        @Override
        public void run() {

            synchronized (resource) {
                System.out.println(Thread.currentThread().getName() + "--获取锁");
                try {
                    System.out.println(Thread.currentThread().getName() + "--准备释放锁");
                    resource.wait();
                    // resource.wait(50L);//验证表明：wait时间到或被中断唤醒，不会继续执行或者跳到catch里
                    // (因为根本得不到执行，根本没法抛出InterruptedException，所以即使catch块放在syschronized外也一样 )，
                    //而是还需要等待获得锁。
                    //如果wait时间到或被中断唤醒，而T2还在syn里，那么T1还是会等待。
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(Thread.currentThread().getName() + "--再次获取到锁");
                try {
                    Thread.sleep(10000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "--仍然持有锁");
            }
            System.out.println(Thread.currentThread().getName() + "--运行结束，释放锁");

        }
    }

    static class Thread2 extends Thread {

        Thread thread1;

        public Thread2(Thread thread1) {
            this.thread1 = thread1;
        }

        @Override
        public void run() {
            synchronized (resource) {
                System.out.println(Thread.currentThread().getName() + "--获取锁");
                try {
                    // 请求中断线程1--此时线程2未释放resource锁
                    thread1.interrupt();
                    // 线程2休眠10秒--此时线程2仍未释放resource锁
                    Thread.sleep(10000L);
                    // 打印此时线程1的状态--线程1处于BLOCKED状态
                    System.out.println(thread1.getState());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "--仍然持有锁");
            }
            System.out.println(Thread.currentThread().getName() + "--运行结束，释放锁");

        }
    }
}  